package com.yequan.spring.bean.definition;

import com.yequan.spring.ioc.overview.domain.User;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

/**
 * BeanDefinition 注册方式:
 * 1. XML
 * 2. java注解:
 * (1)@Bean
 * (2)@Component
 * (3)@Import
 * 3. java API 注册
 * (1).命名方式
 * (2).非命名方式
 * (3).配置类方式
 * <p>
 * 不会重复注册
 *
 * @author : Administrator
 * @date : 2020/4/3
 */
@Import(AnnotationBeanDefinitionDemo.Config.class)// java注解方式注册: 通过@Import 导入配置元信息
public class AnnotationBeanDefinitionDemo {

    public static void main(String[] args) {
        //创建BeanFactory容器
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        //注册 配置类 (configuration class)
        applicationContext.register(AnnotationBeanDefinitionDemo.class);

        //java API方式注册: 命名方式
        registerUserBeanDefinition(applicationContext,"api-user");
        //java API方式注册: 非命名方式
        registerUserBeanDefinition(applicationContext);

        //启动Spring上下文
        applicationContext.refresh();

        //按照类型查找
        System.out.println("Config 类型的所有 Beans " + applicationContext.getBeansOfType(Config.class));
        System.out.println("User 类型的锁有 Beans " + applicationContext.getBeansOfType(User.class));
    }

    /**
     * java API 方式注册:  命名方式
     *
     * @param registry
     * @param beanName
     */
    public static void registerUserBeanDefinition(BeanDefinitionRegistry registry, String beanName) {
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(User.class);
        beanDefinitionBuilder
                .addPropertyValue("id", 1L)
                .addPropertyValue("name", "叶权");
        if (StringUtils.hasText(beanName)) {
            //命名方式注册
            registry.registerBeanDefinition(beanName, beanDefinitionBuilder.getBeanDefinition());
        } else {
            //非命名方式注册
            BeanDefinitionReaderUtils.registerWithGeneratedName(beanDefinitionBuilder.getBeanDefinition(), registry);
        }
    }

    /**
     * java API 方式注册: 非命名方式
     *
     * @param registry
     */
    public static void registerUserBeanDefinition(BeanDefinitionRegistry registry) {
        registerUserBeanDefinition(registry, null);
    }

    /**
     * java注解方式注册: 通过@Component注册
     */
    @Component
    public static class Config {

        /**
         * java注解方式注册: 通过@Bean注册元信息
         *
         * @return
         */
        @Bean(name = "{user,yequan-user}")
        public User user() {
            User user = new User();
            user.setName("yequan");
            user.setId(1L);
            return user;
        }

    }

}
